import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.atomic.*;

/**
 * JSServerThread - Handles an individual client connection to server.
 * 
 * @author James Varvaro
 */
public class JSServerThread extends Thread {
    private Socket socket = null;
    private Drop drop = null;
    private JSMsgProtocolServer protocol;
    private BroadcastDrop broadcast;
    private PrintWriter out = null;
    private volatile boolean running;
    private User user;
    private AtomicLong useridCount;
    
    public JSServerThread(Socket aSocket, BroadcastDrop aBroadcast, AtomicLong serverUseridCount) {
        super("JSServerThread");
        this.socket = aSocket;
        this.drop = new Drop();
        this.protocol = new JSMsgProtocolServer(this);
        this.broadcast = aBroadcast;
        this.useridCount = serverUseridCount;
        this.running = true;
        // Start input handler thread
        new InputHandler(socket, drop).start();
    }
    
    // returns userid
    public long registerUser(String username) {
        long id = useridCount.getAndIncrement();
        user = new User(id, username, "piano");
        System.out.println("User: " + username + " connected.");
        return id;
    }
    
    public void disconnectUser() {
        if(socket.isConnected()){
            try {
                socket.close();
                System.out.println("Server thread socket closed.");
            }
            catch(IOException ex) {
                System.err.println("Could not disconnect client.");
            }
        }
            running = false;
    }
    
    public void broadcastToAll(String msg) {
        broadcast.putOut(msg);
    }
    
    public void broadcastToClient(String msg) {
        out.println(msg);
    }
    
    public void run() {
        try {
            out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                    socket.getInputStream()));
        }
        catch(IOException ex) {
            System.out.println("Can't initiate server thread IO");
        }
       
       while(running) {
           String data = null;
           // print messages in drop
           while((data = drop.poll()) != null) {
               protocol.process(data);
            }
           
            while((data = broadcast.pollIn()) != null) {
               System.out.println("Broadcasted: " + data);
               out.println(data);
            }
           // send some messages
           /*
           out.println("Pirates");
           out.println("zombies");
           out.println("plants");
           */
       }
       
       // Thread has ended
       System.out.println("Closing server thread.");
       Thread.currentThread().interrupt();
       return;
        
        //String inputString, outputString;
        //outputString = "test string";
        
      
    }
}
